/**
 * 简化版AI推理Worker进程
 * 专门用于解决net::ERR_CONNECTION_RESET问题的异步架构
 * 使用CommonJS格式，兼容现有系统
 */

const { Worker } = require('bullmq');
const Redis = require('ioredis');
const path = require('path');
const fs = require('fs').promises;
const axios = require('axios');
const FormData = require('form-data');

// 配置
const REDIS_CONFIG = {
  host: process.env.REDIS_HOST || 'localhost',
  port: parseInt(process.env.REDIS_PORT) || 6379,
  maxRetriesPerRequest: 3,
  retryDelayOnFailover: 100,
  lazyConnect: true
};

const AI_SERVICE_CONFIG = {
  baseURL: process.env.AI_INFERENCE_URL || 'http://localhost:5001/v1/predict',
  timeout: parseInt(process.env.AI_INFERENCE_TIMEOUT) || 90000, // 90秒超时
  maxRetries: 2,
  retryDelay: 2000
};

// 创建Redis连接
const redisConnection = new Redis(REDIS_CONFIG);

// AI推理Worker
const aiInferenceWorker = new Worker(
  'ai-inference-queue',
  async (job) => {
    const { taskId, imagePath, taskData } = job.data;

    job.log(`开始处理AI推理任务: ${taskId}`);

    try {
      // 验证图片文件存在
      try {
        await fs.access(imagePath);
      } catch (error) {
        throw new Error(`图片文件不存在: ${imagePath}`);
      }

      // 准备AI服务请求
      const form = new FormData();
      form.append('image', await fs.readFile(imagePath), path.basename(imagePath));

      // 调用AI服务
      const response = await axios.post(AI_SERVICE_CONFIG.baseURL, form, {
        headers: form.getHeaders(),
        timeout: AI_SERVICE_CONFIG.timeout,
        maxContentLength: Infinity,
        maxBodyLength: Infinity
      });

      // 验证AI响应
      if (!response.data || !response.data.success) {
        throw new Error(`AI服务返回错误: ${response.data?.message || '未知错误'}`);
      }

      const aiResult = response.data.data;

      // 构建结果数据
      const result = {
        taskId,
        status: 'completed',
        aiResult,
        completedAt: new Date().toISOString(),
        processingTime: Date.now() - taskData.createdAt
      };

      job.log(`AI推理任务完成: ${taskId}, 耗时: ${result.processingTime}ms`);

      return result;

    } catch (error) {
      job.log(`AI推理任务失败: ${taskId}, 错误: ${error.message}`);

      // 构建失败结果
      const errorResult = {
        taskId,
        status: 'failed',
        error: {
          message: error.message,
          code: error.code || 'AI_INFERENCE_ERROR',
          type: error.code === 'ETIMEDOUT' ? 'TIMEOUT' : 'SERVICE_ERROR'
        },
        failedAt: new Date().toISOString(),
        processingTime: Date.now() - taskData.createdAt
      };

      // 如果是超时错误，进行特殊标记
      if (error.code === 'ETIMEDOUT' || error.message.includes('timeout')) {
        errorResult.error.type = 'TIMEOUT';
        errorResult.error.recoverable = true;
      }

      throw errorResult;
    }
  },
  {
    connection: redisConnection,
    concurrency: parseInt(process.env.AI_WORKER_CONCURRENCY) || 2, // 最多并发2个AI任务
    limiter: {
      max: 10, // 每10秒最多处理10个任务
      duration: 10000
    }
  }
);

// Worker事件监听
aiInferenceWorker.on('completed', (job, result) => {
  console.log(`✅ AI推理任务完成: ${job.id}, TaskId: ${result.taskId}`);

  // 更新任务状态到数据库（这里可以通过数据库连接或API调用）
  updateTaskStatus(result.taskId, {
    status: 'completed',
    ai_result: result.aiResult,
    completed_at: result.completedAt,
    processing_time: result.processingTime
  }).catch(error => {
    console.error(`更新任务状态失败: ${result.taskId}`, error);
  });
});

aiInferenceWorker.on('failed', (job, err) => {
  const errorResult = err;
  console.error(`❌ AI推理任务失败: ${job.id}, TaskId: ${errorResult.taskId}`, errorResult.error);

  // 更新失败状态到数据库
  updateTaskStatus(errorResult.taskId, {
    status: 'failed',
    error_message: errorResult.error.message,
    error_code: errorResult.error.code,
    error_type: errorResult.error.type,
    failed_at: errorResult.failedAt,
    processing_time: errorResult.processingTime
  }).catch(error => {
    console.error(`更新失败任务状态失败: ${errorResult.taskId}`, error);
  });
});

aiInferenceWorker.on('error', (err) => {
  console.error('🚨 AI Worker进程错误:', err);
});

// 任务状态更新函数
async function updateTaskStatus(taskId, statusData) {
  try {
    // 这里需要连接到数据库更新状态
    // 暂时通过日志记录，后续可以集成数据库连接池
    console.log(`📊 更新任务状态: ${taskId}`, statusData);

    // TODO: 集成数据库更新逻辑
    // await db.query(
    //   'UPDATE scoring_tasks SET status = ?, ai_result = ?, completed_at = ?, error_message = ? WHERE task_id = ?',
    //   [statusData.status, JSON.stringify(statusData.ai_result), statusData.completed_at, statusData.error_message, taskId]
    // );

  } catch (error) {
    console.error(`更新任务状态失败: ${taskId}`, error);
    throw error;
  }
}

// 优雅关闭处理
process.on('SIGINT', async () => {
  console.log('🛑 收到SIGINT信号，开始优雅关闭AI Worker...');

  await aiInferenceWorker.close();
  await redisConnection.quit();

  console.log('✅ AI Worker已优雅关闭');
  process.exit(0);
});

process.on('SIGTERM', async () => {
  console.log('🛑 收到SIGTERM信号，开始优雅关闭AI Worker...');

  await aiInferenceWorker.close();
  await redisConnection.quit();

  console.log('✅ AI Worker已优雅关闭');
  process.exit(0);
});

// 启动信息
console.log('🚀 简化版AI推理Worker已启动');
console.log(`📍 Redis连接: ${REDIS_CONFIG.host}:${REDIS_CONFIG.port}`);
console.log(`🤖 AI服务: ${AI_SERVICE_CONFIG.baseURL}`);
console.log(`⏱️ 超时配置: ${AI_SERVICE_CONFIG.timeout}ms`);
console.log(`🔄 并发限制: ${aiInferenceWorker.opts.concurrency}`);

// 导出worker供测试使用
module.exports = aiInferenceWorker;